﻿using Microsoft.Win32;
using System.Diagnostics;
using System.ServiceProcess;

namespace JLHelper
{
    public class WindowsServiceHelper
    {
        #region 已封装Window服务

        /// <summary>  
        /// 安装服务  
        /// </summary>  
        /// <param name="serviceName">Windows服务显示名称</param>
        /// <param name="servicePath">服务路径</param>
        /// <param name="serviceDescription">服务备注</param>
        /// <param name="killProcessID">启动服务前需要关闭的进程ID</param>
        /// /// <param name="killProcessName">启动服务前需要关闭的进程名称</param>
        /// <returns>成功 true,失败 false;</returns>  
        public static bool InstallService(string serviceName, string servicePath, string serviceDescription = "", int killProcessID = -1, string killProcessName = "")
        {

            bool flag = false;
            if (!IsServiceIsExisted(serviceName))
            {
                using (Process p = new Process())
                {
                    p.StartInfo.FileName = @"sc.exe";//可执行程序路径
                    p.StartInfo.Arguments = "create " + serviceName + " binPath= \"" + servicePath + "\" start= auto displayname= " + serviceName;//参数以空格分隔，如果某个参数为空，可以传入""
                    p.StartInfo.UseShellExecute = true;//是否使用操作系统shell启动
                    p.StartInfo.CreateNoWindow = true;//不显示程序窗口
                    p.StartInfo.Verb = "runas";
                    p.Start();
                    p.WaitForExit();

                    //正常运行结束放回代码为0
                    if (p.ExitCode == 0)
                    {
                        //增加服务备注
                        p.StartInfo.FileName = @"sc.exe";//可执行程序路径
                        p.StartInfo.Arguments = "description " + serviceName + " " + serviceDescription;//参数以空格分隔，如果某个参数为空，可以传入""
                        p.StartInfo.UseShellExecute = true;//是否使用操作系统shell启动
                        p.StartInfo.CreateNoWindow = true;//不显示程序窗口
                        p.StartInfo.Verb = "runas";
                        p.Start();
                        p.WaitForExit();

                        //根据进程ID关闭进程
                        if (killProcessID != -1)
                        {
                            try
                            {
                                System.Diagnostics.Process kp = System.Diagnostics.Process.GetProcessById(killProcessID);
                                kp.Kill();
                            }
                            catch (Exception ex)
                            {

                            }
                        }

                        //根据进程名关闭进程
                        if (!string.IsNullOrWhiteSpace(killProcessName))
                        {
                            try
                            {
                                System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(killProcessName);
                                foreach (System.Diagnostics.Process kp in ps)
                                {
                                    kp.Kill();
                                }
                            }
                            catch (Exception ex)
                            {

                            }
                        }

                        //启动服务
                        StartService(serviceName);

                        flag = true;
                    }


                }

                flag = true;
            }

            return flag;
        }

        /// <summary>  
        /// 卸载服务  
        /// </summary>  
        /// <param name="NameService">Windows服务显示名称</param>  
        /// <returns>存在返回 true,否则返回 false;</returns>  
        public static bool UninstallService(string serviceName)
        {
            bool flag = false;
            if (IsServiceIsExisted(serviceName))
            {
                using (Process p = new Process())
                {
                    p.StartInfo.FileName = @"sc.exe";//可执行程序路径
                    p.StartInfo.Arguments = "stop " + serviceName;//参数以空格分隔，如果某个参数为空，可以传入""
                    p.StartInfo.UseShellExecute = true;//是否使用操作系统shell启动
                    p.StartInfo.CreateNoWindow = true;//不显示程序窗口
                    p.StartInfo.Verb = "runas";
                    p.Start();
                    p.WaitForExit();
                    //正常运行结束放回代码为0
                    if (p.ExitCode == 0)
                    {
                        p.StartInfo.FileName = @"sc.exe";//可执行程序路径
                        p.StartInfo.Arguments = "delete " + serviceName;//参数以空格分隔，如果某个参数为空，可以传入""
                        p.StartInfo.UseShellExecute = true;//是否使用操作系统shell启动
                        p.StartInfo.CreateNoWindow = true;//不显示程序窗口
                        p.StartInfo.Verb = "runas";
                        p.Start();
                        p.WaitForExit();
                        //正常运行结束放回代码为0
                        if (p.ExitCode == 0)
                        {
                            flag = true;
                        }
                    }


                }
            }
            return flag;
        }

        /// <summary>  
        /// 检查Windows服务是否存在  
        /// </summary>  
        /// <param name="NameService">Windows服务显示名称</param>  
        /// <returns>存在返回 true,否则返回 false;</returns>  
        public static bool IsServiceIsExisted(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController s in services)
            {
                if (s.ServiceName.ToLower() == serviceName.ToLower())
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 判断某个Windows服务是否启动  
        /// </summary>
        /// <param name="serviceName">Windows服务显示名称</param>
        /// <returns>bool</returns>
        public static bool IsServiceStart(string serviceName)
        {
            ServiceController psc = new ServiceController(serviceName);
            bool bStartStatus = false;
            try
            {
                if (!psc.Status.Equals(ServiceControllerStatus.Stopped))
                {
                    bStartStatus = true;
                }

                return bStartStatus;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }


        /// <summary>    
        /// 修改服务的启动项 2为自动,3为手动    
        /// </summary>    
        /// <param name="startType">2为自动,3为手动</param>    
        /// <param name="serviceName">Windows服务显示名称</param>    
        /// <returns>bool</returns>    
        public static bool ChangeServiceStartType(int startType, string serviceName)
        {
            try
            {
                RegistryKey regist = Registry.LocalMachine;
                RegistryKey sysReg = regist.OpenSubKey("SYSTEM");
                RegistryKey currentControlSet = sysReg.OpenSubKey("CurrentControlSet");
                RegistryKey services = currentControlSet.OpenSubKey("Services");
                RegistryKey servicesName = services.OpenSubKey(serviceName, true);
                servicesName.SetValue("Start", startType);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;


        }

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="serviceName">Windows服务显示名称</param>
        /// <returns>bool</returns>
        public static bool StartService(string serviceName)
        {
            bool flag = true;
            if (IsServiceIsExisted(serviceName))
            {
                System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);
                if (service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status != System.ServiceProcess.ServiceControllerStatus.StartPending)
                {
                    service.Start();
                    for (int i = 0; i < 60; i++)
                    {
                        service.Refresh();
                        System.Threading.Thread.Sleep(1000);
                        if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                        {
                            break;
                        }
                        if (i == 59)
                        {
                            flag = false;
                        }
                    }
                }
            }
            return flag;
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="serviceName">Windows服务显示名称</param>
        /// <returns>bool</returns>
        public static bool StopService(string serviceName)
        {
            bool flag = true;
            if (IsServiceIsExisted(serviceName))
            {
                System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController(serviceName);
                if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
                {
                    service.Stop();
                    for (int i = 20; i <= 0; i--)
                    {
                        service.Refresh();
                        System.Threading.Thread.Sleep(1000);
                        if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)
                        {
                            break;
                        }
                        if (i == 1)
                        {
                            flag = false;
                        }
                    }
                }
            }
            return flag;
        }



        #endregion
    }

}
